
package middleware;

public class Command {

    final int USR_LOGIN = 1;
    final int USR_METADATA_REQ = 2;
    final int USR_GET_PIC_REQ = 3;
    final int USR_CREATE_NEW = 4;
    final int USR_SET_PICTURE = 5;
    final int USR_ADD_EVENT = 6;
    final int USR_DELETE_EVENT = 7;
    final int USR_EVENT_RANGE = 8;

    final int GET_DAY = 9;
    
    final int ADMIN_DELETE_USER = 10;
    final int ADMIN_LIST_USERS = 11;

    final int USR_UPDATE_PASSWD = 12;
    final int USR_HAS_PIC = 13;

    final int USR_SUICIDE = 14;

    int cmdI;
    boolean errorWrongArgs = false;
    String commandParse = "";
    String cmd;
    String[] args;
    String[] input;

    public Command(String command) {
        
        String[] encStr = command.split("&");
        if(encStr.length > 1){
            args = new String[encStr.length-1];
            input = new String[encStr.length-1];

        }
        for(int i = 0; i < encStr.length; i++){
            if(i==0){
                cmd = unescape(encStr[i].split("=")[0]);
            }else{
                String[] var = unescape(encStr[i]).split("=");
                args[i-1] = var[0];
                input[i-1] = var.length > 1 ? var[1] : "";
            }
        }
        pr("\n========== COMMAND ===========");
        pr(cmd);
        if(encStr.length > 1)
            for(int i = 0; i < args.length; i++){
                pr(args[i] + "  :: " + input[i]);
            }
        pr("==============================\n");

        setIntCmd();
    }

    String getInput(String arg){
        for(int i = 0; i < args.length; i++)
            if(arg.equals(args[i]))
                return input[i];
        return "";
    }

    void setIntCmd(){
        if(cmd.equalsIgnoreCase("USR_LOGIN")){
            cmdI=USR_LOGIN;
            commandParse="USR_LOGIN=&USERNAME=<string>&PASSWD=<string>";
            errorWrongArgs = !isValidArgs(args, new String[]{"USERNAME", "PASSWD"});
        }
        else if(cmd.equalsIgnoreCase("USR_METADATA_REQ")){
            cmdI=USR_METADATA_REQ;
            commandParse="USR_METADATA_REQ=&SESSION=<session>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION"});
        }
        else if(cmd.equalsIgnoreCase("USR_GET_PIC_REQ")){
            cmdI=USR_GET_PIC_REQ;
            commandParse="USR_GET_PIC_REQ=&SESSION=<session>[&USERNAME=<string>]";
            if(args.length == 1){
                errorWrongArgs = !isValidArgs(args, new String[]{"SESSION"});
            }else{
                errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "USERNAME"});
            }
        }
        else if(cmd.equalsIgnoreCase("USR_CREATE_NEW")){
            cmdI=USR_CREATE_NEW;
            commandParse="USR_CREATE_NEW=&USERNAME=<string>&PASSWORD=<string>&NAME=<string>";
            errorWrongArgs = !isValidArgs(args, new String[]{"USERNAME", "PASSWORD", "NAME"});
        }
        else if(cmd.equalsIgnoreCase("USR_SET_PICTURE")){
            cmdI=USR_SET_PICTURE;
            commandParse="USR_SET_PICTURE=&SESSION=<session>&IMAGE=<string>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "IMAGE"});
        }
        else if(cmd.equalsIgnoreCase("USR_ADD_EVENT")){
            cmdI=USR_ADD_EVENT;
            commandParse="USR_ADD_EVENT=&SESSION=<session>&DESC=<string>&START=<long>&STOP<long>&PUBSHARE<boolean>&ETYPE=<string>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "DESC", "START", "STOP", "PUBSHARE", "ETYPE"});
        }
        else if(cmd.equalsIgnoreCase("USR_DELETE_EVENT")){
            cmdI=USR_DELETE_EVENT;
            commandParse="USR_DELETE_EVENT=&SESSION=<session>&EID=<int>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "EID"});
        }
        else if(cmd.equalsIgnoreCase("USR_EVENT_RANGE")){
            cmdI=USR_EVENT_RANGE;
            commandParse="USR_EVENT_RANGE=&SESSION=<session>&START=<long>&END=<long>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "START", "END"});
        }

        else if(cmd.equalsIgnoreCase("GET_DAY")){
            cmdI=GET_DAY;
            commandParse="SESSION=&SESSION=<session>&YEAR=<int>&MONTH=<int>&DAY=<int>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "YEAR", "MONTH", "DAY"});
        }
        else if(cmd.equalsIgnoreCase("ADMIN_DELETE_USER")){
            cmdI=ADMIN_DELETE_USER;
            commandParse="ADMIN_DELETE_USER=&SESSION=<session>&UID=<int>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "UID"});
        }
        else if(cmd.equalsIgnoreCase("ADMIN_LIST_USERS")){
            cmdI=ADMIN_LIST_USERS;
            commandParse="ADMIN_LIST_USERS=&SESSION=<session>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION"});
        }
        else if(cmd.equalsIgnoreCase("USR_UPDATE_PASSWD")){
            cmdI=USR_UPDATE_PASSWD;
            commandParse="USR_UPDATE_PASSWD=&SESSION=<session>&OLD_PWD=<string>&NEW_PWD=<string>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "OLD_PWD", "NEW_PWD"});
        }
        else if(cmd.equalsIgnoreCase("USR_HAS_PIC")){
            cmdI=USR_HAS_PIC;
            commandParse="USR_HAS_PIC=&SESSION=<session>[&USERNAME=<string>]";
            if(args.length == 1){
                errorWrongArgs = !isValidArgs(args, new String[]{"SESSION"});
            }else{
                errorWrongArgs = !isValidArgs(args, new String[]{"SESSION", "USERNAME"});
            }
        }
        else if(cmd.equalsIgnoreCase("USR_SUICIDE")){
            cmdI=USR_SUICIDE;
            commandParse="USR_SUICIDE?SESSION=<session>";
            errorWrongArgs = !isValidArgs(args, new String[]{"SESSION"});
        }

        else{cmdI=0;}
    }

    boolean isValidArgs(String[] args, String[] args2){
        if (args != null) {
            if(args.length == args2.length){
                for(int i = 0; i < args.length; i++){
                    if(!args[i].equalsIgnoreCase(args2[i])){
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }

// TODO decode beroende på vilken encoding.
    private static String unescape(String s) {
        StringBuffer sbuf = new StringBuffer () ;
        int l  = s.length() ;
        int ch = -1 ;
        int b, sumb = 0;
        for (int i = 0, more = -1 ; i < l ; i++) {
            /* Get next byte b from URL segment s */
            switch (ch = s.charAt(i)) {
                case '%':
                ch = s.charAt (++i) ;
                int hb = (Character.isDigit ((char) ch)
                ? ch - '0'
                : 10+Character.toLowerCase((char) ch) - 'a') & 0xF ;
                ch = s.charAt (++i) ;
                int lb = (Character.isDigit ((char) ch)
                ? ch - '0'
                : 10+Character.toLowerCase ((char) ch)-'a') & 0xF ;
                b = (hb << 4) | lb ;
                break ;
                case '+':
                b = ' ' ;
                break ;
                default:
                b = ch ;
            }
            /* Decode byte b as UTF-8, sumb collects incomplete chars */
            if ((b & 0xc0) == 0x80) {			// 10xxxxxx (continuation byte)
                sumb = (sumb << 6) | (b & 0x3f) ;	// Add 6 bits to sumb
                if (--more == 0) sbuf.append((char) sumb) ; // Add char to sbuf
            } else if ((b & 0x80) == 0x00) {		// 0xxxxxxx (yields 7 bits)
                sbuf.append((char) b) ;			// Store in sbuf
            } else if ((b & 0xe0) == 0xc0) {		// 110xxxxx (yields 5 bits)
                sumb = b & 0x1f;
                more = 1;				// Expect 1 more byte
            } else if ((b & 0xf0) == 0xe0) {		// 1110xxxx (yields 4 bits)
                sumb = b & 0x0f;
                more = 2;				// Expect 2 more bytes
            } else if ((b & 0xf8) == 0xf0) {		// 11110xxx (yields 3 bits)
                sumb = b & 0x07;
                more = 3;				// Expect 3 more bytes
            } else if ((b & 0xfc) == 0xf8) {		// 111110xx (yields 2 bits)
                sumb = b & 0x03;
                more = 4;				// Expect 4 more bytes
            } else /*if ((b & 0xfe) == 0xfc)*/ {	// 1111110x (yields 1 bit)
                sumb = b & 0x01;
                more = 5;				// Expect 5 more bytes
            }
            /* We don't test if the UTF-8 encoding is well-formed */
        }
        return sbuf.toString() ;
    }


    void pr(Object o){
        String debug = System.getProperty("debug");
        if (debug != null && debug.equals("1")) {
            System.out.println(""+o);
        }
    }
}
